package codename.carrot.bomberman.network.client;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;

import android.util.Log;
import codename.carrot.bomberman.network.MessageHandler;
import codename.carrot.bomberman.network.NetworkConnection;
import codename.carrot.bomberman.network.NetworkConnection.NetworkState;

/**
 * Set up and connect to the network as a client.
 * 
 * @author Group A4.
 *
 */
public class Client extends Thread {

	/**
	 * String for debugging.
	 */
	private String DEBUG = this.getClass().getSimpleName();
	/**
	 * Socket endpoint used for connecting the socket.
	 */
	private InetSocketAddress address;
	/**
	 * The socket for connecting.
	 */
	private Socket socket;
	/**
	 * The ClientConnection connection (for adding a new connection).
	 */
	private ClientConnection clientConnection;
	/**
	 * The Message handler.
	 */
	private MessageHandler messageHandler;
	
	/**
	 * Constructs a Client with a IP, client connection and message handler.
	 * @param ip The ip-address to connect to.
	 * @param clientConnection The client connection.
	 * @param messageHandler The message handler.
	 */
	public Client(String ip, ClientConnection clientConnection, MessageHandler messageHandler) {
		this.messageHandler = messageHandler;
		this.clientConnection = clientConnection;
		address = new InetSocketAddress(ip, NetworkConnection.PORT);
		try {
			socket = new Socket();
		} catch (Exception e) {
			clientConnection.setState(NetworkState.ERROR);
			clientConnection.terminate();
			Log.e(DEBUG, "Failed to create socket.", e);
		}
	}

	/**
	 * Terminates the client. and interrupt the thread.
	 */
	public void terminate() {
		try {
			if(socket != null)
				socket.close();
			address = null;
			socket = null;
			interrupt();
			System.out.println("CLIENT IS CLOSED");
		} catch (Exception e) {
			Log.e(DEBUG, "Failed to terminate client!", e);
		}
	}

	@Override
	public void run() {
		try {
			socket.connect(address, 5000);

			if (socket.isConnected()) {
				clientConnection.setState(NetworkState.CONNECTING);
				ClientConnectionThread ct = new ClientConnectionThread(socket, 0, clientConnection, messageHandler);
				synchronized (clientConnection) {
					clientConnection.setConnection(ct);
					ct.start();
				}
			}
		} catch (IOException e) {
			Log.d(DEBUG, "Socket connect failed", e);
			clientConnection.setState(NetworkState.ERROR);
		}
	}
	

}
